package com.xca.gsondemo.utils;

import android.content.Context;
import android.content.res.AssetManager;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class JsonUtils {

   /**
    * 获取assets目录下json文件中的字符串
    * @param context
    * @param fileName 文件名
    * @return
    */
   public static String getJsonFromAssets(Context context, String fileName) {
      //将json数据变成字符串

      StringBuilder stringBuilder = new StringBuilder();
      try {
         //获取assets资源管理器
         AssetManager assetManager = context.getAssets();
         //通过管理器打开文件并读取
         BufferedReader bf = new BufferedReader(new InputStreamReader(
                 assetManager.open(fileName)));
         String line;
         while ((line = bf.readLine()) != null) {
            stringBuilder.append(line);
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
      return stringBuilder.toString();
   }

   /**
    * Json字符串转JavaBean
    *
    */
   public static <T> T jsonToObj(String json, Class<T> cls) {
      if (TextUtils.isEmpty(json) || null == cls) return null;
      T t = null;
      try {
         t = new Gson().fromJson(json, cls);
      } catch (JsonSyntaxException e) {
         e.printStackTrace();
      }
      return t;
   }

   /**
    * Json转List
    *
    */
   public static <T> List<T> jsonToList(String json, Class<T> cls) {
      if (TextUtils.isEmpty(json) || null == cls) return null;
      List<T> list = new ArrayList<>();
      try {
         Gson gson = new Gson();
         JsonArray jsonArray = JsonParser.parseString(json).getAsJsonArray();
         for (JsonElement jsonElement : jsonArray) {
            list.add(gson.fromJson(jsonElement, cls));
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
      return list;
   }

   /**
    * Java对象转Json字符串
    * @param obj
    * @return
    */
   public static String objToJson(Object obj) {
      if (null == obj) return "";
      String result = null;
      try {
         result = new Gson().toJson(obj);
      } catch (Exception e) {
         e.printStackTrace();
      }
      return result;
   }

   /**
    * 判断字符串是否是json格式
    * @param jsonStr
    * @return
    */
   public static boolean isJson(String jsonStr) {
      try {
         new JSONObject(jsonStr);
      } catch (JSONException e) {
         return false;
      }
      return true;
   }

   public static String getJsonValue(String jsonStr, String key) {
      try {
         Gson g = new Gson();
         Map<String, Object> map = g.fromJson(jsonStr, new TypeToken<Map<String, Object>>() {}.getType());
         Object obj = map.get(key);
         if (obj != null) {
            return obj.toString();
         }
         return "";
      } catch (Exception e) {
         return "";
      }
   }

   public static String getJsonValue(String jsonStr, String key1, String key2) {
      try {
         Gson gson = new Gson();
         Map<String, Object> map1 = gson.fromJson(jsonStr, new TypeToken<Map<String, Object>>() {
         }.getType());
         if (map1 == null) {
            return "";
         }
         Map<String, Object> map2 = (Map<String, Object>) map1.get(key1);
         if (map2 == null) {
            return "";
         }
         Object obj = map2.get(key2);
         if (obj == null) {
            return null;
         }
         return obj.toString();
      } catch (Exception e) {
         return "";
      }
   }

   /**
    * 递归获取某个Key对应的值，非JsonArray
    * @param jsonStr
    * @param key
    * @return
    */
   public static String getKeyRecursively(String jsonStr, String key) {
      Gson gson = new Gson();
      JsonElement rootElement = gson.fromJson(jsonStr, JsonElement.class);
      if (!rootElement.isJsonObject()) {
         return "";
      }
      JsonElement jsonElement = findKeyRecursively(rootElement.getAsJsonObject(), key);
      if (jsonElement.isJsonNull()) {
         return "";
      }
      return jsonElement.getAsString();
   }

   public static JsonElement findKeyRecursively(JsonObject json, String key) {
      if (json.has(key)) {
         return json.get(key);
      }
      for (Map.Entry<String, JsonElement> entry : json.entrySet()) {
         if (entry.getValue().isJsonObject()) {
            JsonElement result = findKeyRecursively(entry.getValue().getAsJsonObject(), key);
            if (!result.isJsonNull()) {
               return result;
            }
         }
      }
      return JsonNull.INSTANCE;
   }
}
